package com.mud.dnd.domain.dao;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionManagement;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.mud.dnd.domain.common.DAOException;
import com.mud.dnd.domain.common.QueryParameter;
import com.mud.dnd.domain.common.QueryParameter.QueryParamOperator;
import com.mud.dnd.domain.model.Action;
import com.mud.dnd.domain.model.Card;
import com.mud.dnd.domain.model.CardAction;
import com.mud.dnd.domain.model.Comment;
import com.mud.dnd.domain.model.Deck;
import com.mud.dnd.domain.model.DnDItem;
import com.mud.dnd.domain.model.GameItem;
import com.mud.dnd.domain.model.Session;
import com.mud.dnd.domain.model.User;
import com.mud.dnd.domain.model.User.Role;

/**
 * Session Bean implementation class ivosDAO
 */

@Stateless
@TransactionManagement
public class DnDDAOImpl implements DnDDAO {

	
	@PersistenceContext
	private EntityManager em;
	
	
    /**
     * Default constructor. 
     */
    public DnDDAOImpl() {
        
    }
    
    
    @Override
	@TransactionAttribute
	public GameItem getGameItembyID(int id) throws DAOException {
		GameItem item = em.find(GameItem.class, id);
		if(item==null)
		{
			throw new DAOException("Not existing game item.");
		}
		
		return item;
		
	}
    
    @Override
	@TransactionAttribute
	public void updateGameItem(int id, String name, String description,
			String pictureURL,String picturePath,  int rate) throws DAOException {

		GameItem gameItem = em.find(GameItem.class,	 id);
		if(gameItem==null)
		{
			throw new DAOException("Not existing deck.");
		}
		
		if(name != null)
		{
			gameItem.setName(name);
		}
		
		if(description!=null)
		{
			gameItem.setDescription(description);
		}
		
		if(pictureURL!=null)
		{
			gameItem.setPictureURL(pictureURL);
		}
		
		if(picturePath!=null)
		{
			gameItem.setPicturePath(picturePath);
		}
		
		if(rate!=0)
		{
			double currentSum = (gameItem.getRate() * gameItem.getRateCount());
			currentSum+= rate;
			gameItem.setRateCount(gameItem.getRateCount()+1);
			gameItem.setRate(currentSum/gameItem.getRateCount());
		}
		
		
		//em.merge(gameItem);
		
	}
    
    
    @Override
   	@TransactionAttribute
    public int getDnDItemOwnerID(int id) throws DAOException
    {
    	
    	DnDItem item = em.find(DnDItem.class,id);
		if(item==null)
		{
			throw new DAOException("Not existing game item.");
		}
		
		return item.getAuthor().getId();
    }
    
    /* (non-Javadoc)
	 * @see com.mud.dnd.domain.dao.IDnDDAO#getAllCards()
	 */
    @Override
	@TransactionAttribute
    public List<Card> getCards(List<QueryParameter> params)
    {
    	StringBuilder query = new StringBuilder("select distinct c from Card c left join fetch c.actions ca left join fetch ca.action a");
    	
    	
    	
    	if(!params.isEmpty())
    	{
    		for(QueryParameter param : params)
    		{
    			if(param.getParamName().equals("deckID"))
    			{
    				
    				query.append(" inner join c.decks d ");
    			}
    		}
    		
    		query.append(" where ");
    		
    		int listCounter=1;
	    	for(QueryParameter param : params)
	    	{
	    		
	    		if(param.getParamName().equals("deckID"))
	    		{
	    			query.append(" d.id ");
	    		}
	    		else if(param.getParamName().equals("author"))
	    		{
	    			query.append(" c.author.name ");
	    		}
	    		else
	    		{
	    			query.append(" c."+param.getParamName()+" ");
	    		}
	    		
	    		
	    		String op = "";
	    		switch (param.getOperator()){
				case LESS:
					op ="<=";
					break;
				case MORE:
					op =">=";
					break;
				case EQUALS:
					op ="=";
					break;
				case LIKE:
					op ="like";
					break;

				default:
					op ="=";
					break;
				}
	    		
	    		query.append(op);
	    		query.append(" :"+param.getParamName()+" ");
	    		
	    		if(listCounter<params.size())
	    		{
	    			query.append(" and ");
	    		}
	    		
	    		listCounter++;
	    		
	    	}
    	}
    	
    	query.append(" order by c.name ");
    	
    	Query emQuery = em.createQuery(query.toString());
    	
    	for(QueryParameter param : params)
    	{
    		
    		
    		if(param.getOperator()== QueryParamOperator.LIKE)
    		{
    			String value = (String) param.getValue();
    			value = "%"+value+"%";
    			emQuery.setParameter(param.getParamName(), value);
    		}
    		else
    		{
    			emQuery.setParameter(param.getParamName(), param.getValue());
    		}
    		
    	}
    	
    	return emQuery.getResultList();
    }
    
    /* (non-Javadoc)
	 * @see com.mud.dnd.domain.dao.IDnDDAO#createCard(java.lang.String, java.lang.String, java.lang.String, int, java.lang.String)
	 */
    @Override
	@TransactionAttribute
    public int createCard(String name, String description, String pictureURL,
			 String type, int rarity, User author) throws DAOException
    {
    	Card newCard = new Card(name, description, pictureURL, type, rarity, author);
    	newCard.setDecks(new ArrayList<Deck>());
    	newCard.setActions(new ArrayList<CardAction>());
    	
    	em.persist(newCard);	
    	return newCard.getId();

    }
    
    
    
    
    /* (non-Javadoc)
	 * @see com.mud.dnd.domain.dao.IDnDDAO#getAllDecks()
	 */
    @Override
	@TransactionAttribute
    public List<Deck> getDecks(List<QueryParameter> params)
    {
    	
    	StringBuilder query = new StringBuilder("select d from Deck d");
    	if(!params.isEmpty())
    	{
    		for(QueryParameter param : params)
    		{
    			if(param.getParamName().equals("cardID"))
    			{
    				
    				query.append(" inner join d.cards c ");
    			}
    		}
    		
    		query.append(" where ");
    		
    		int listCounter=1;
	    	for(QueryParameter param : params)
	    	{
	    		if(param.getParamName().equals("cardID"))
	    		{
	    			query.append(" c.id ");
	    		}
	    		else if(param.getParamName().equals("author"))
	    		{
	    			query.append(" d.author.name ");
	    		}
	    		else
	    		{
	    			query.append(" d."+param.getParamName()+" ");
	    		}
	    		
	    		String op = "";
	    		switch (param.getOperator()){
				case LESS:
					op ="<=";
					break;
				case MORE:
					op =">=";
					break;
				case EQUALS:
					op ="=";
					break;
				case LIKE:
					op ="like";
					break;

				default:
					op ="=";
					break;
				}
	    		
	    		query.append(op);
	    		query.append(" :"+param.getParamName()+" ");
	    		
	    		if(listCounter<params.size())
	    		{
	    			query.append(" and ");
	    		}
	    		
	    		listCounter++;
	    		
	    	}
    	}
    	
    	query.append(" order by d.name ");
    	
    	Query emQuery = em.createQuery(query.toString());
    	
    	for(QueryParameter param : params)
    	{
    		
    		if(param.getOperator()== QueryParamOperator.LIKE)
    		{
    			String value = (String) param.getValue();
    			value = "%"+value+"%";
    			emQuery.setParameter(param.getParamName(), value);
    		}
    		else
    		{
    			emQuery.setParameter(param.getParamName(), param.getValue());
    		}
    		
    	}
    	
    	return emQuery.getResultList();
    }
    
    /* (non-Javadoc)
	 * @see com.mud.dnd.domain.dao.IDnDDAO#createDeck(java.lang.String, java.lang.String, java.lang.String)
	 */
    @Override
	@TransactionAttribute
    public int createDeck(String name, String description, String pictureURL, User author)
    {
    	Deck deck = new Deck(name, description, pictureURL,author);
        deck.setCards(new ArrayList<Card>());
       
        em.persist(deck);
        
        return deck.getId();
    
    }
    
    
    
    /* (non-Javadoc)
	 * @see com.mud.dnd.domain.dao.IDnDDAO#addCardtoDeck(int, int)
	 */
    @Override
	@TransactionAttribute
    public void addCardtoDeck(int cardID, int deckID) throws DAOException
    {
    	Deck deck = em.find(Deck.class, deckID);
    	if(deck == null)
    	{
    		throw new DAOException("Not exsisting deck.");
    	}
    	
    	Card card = em.find(Card.class, cardID);
    	if(card== null)
    	{
    		throw new DAOException("Not existing card.");
    	}
    	
    	if(deck.getCards()==null)
    	{
    		deck.setCards(new ArrayList<Card>());
    	}
    	
    	for(Card c : deck.getCards())
    	{
    		if(c.getId()==cardID)
    		{
    			throw new DAOException("The card is already added to the deck.");
    		}
    	}
    	
    	card.getDecks().add(deck);
    	deck.getCards().add(card);
    	
    	em.merge(card);
    	em.merge(deck);
    }

	@Override
	@TransactionAttribute
	public void updateCard(int id, String name, String description,
			String pictureURL,String picturePath, String type, int rate, int rarity) throws DAOException {
		
		Card card = em.find(Card.class,	 id);
		if(card==null)
		{
			throw new DAOException("Not existing card.");
		}
		
		if(name != null)
		{
			card.setName(name);
		}
		
		if(description!=null)
		{
			card.setDescription(description);
		}
		
		if(pictureURL!=null)
		{
			card.setPictureURL(pictureURL);
		}
		
		if(picturePath!=null)
		{
			card.setPicturePath(picturePath);
		}
		
		if(type!= null)
		{
			card.setType(type);
		}
		
		if(rarity!=0)
		{
			card.setRarity(rarity);
		}
		
		if(rate!=0)
		{
			double currentSum = (card.getRate() * card.getRateCount());
			currentSum+= rate;
			card.setRateCount(card.getRateCount()+1);
			card.setRate(currentSum/card.getRateCount());
		}
		
		em.merge(card);
		
	}

	@Override
	@TransactionAttribute
	public void deleteCard(int id) throws DAOException {
		Card card = em.find(Card.class, id);
		if(card==null)
		{
			throw new DAOException("Not existing card.");
		}
		
		for(Deck deck : card.getDecks())
		{
			deck.getCards().remove(card);
			em.merge(deck);
		}
		for(CardAction cardAction : card.getActions())
		{
			Action action = cardAction.getAction();	
			action.getCards().remove(cardAction);
			em.merge(action);
			em.remove(cardAction);
		}
		
		deleteCommentsForGameItem(card.getId());
		
		em.remove(card);
		
	}

	@Override
	@TransactionAttribute
	public void updateDeck(int id, String name, String description,
			String pictureURL,String picturePath,  int rate) throws DAOException {

		Deck deck = em.find(Deck.class,	 id);
		if(deck==null)
		{
			throw new DAOException("Not existing deck.");
		}
		
		if(name != null)
		{
			deck.setName(name);
		}
		
		if(description!=null)
		{
			deck.setDescription(description);
		}
		
		if(pictureURL!=null)
		{
			deck.setPictureURL(pictureURL);
		}
		
		if(picturePath!=null)
		{
			deck.setPicturePath(picturePath);
		}
		
		if(rate!=0)
		{
			double currentSum = (deck.getRate() * deck.getRateCount());
			currentSum+= rate;
			deck.setRateCount(deck.getRateCount()+1);
			deck.setRate(currentSum/deck.getRateCount());
		}
		
		
		em.merge(deck);
		
	}

	@Override
	@TransactionAttribute
	public void deleteDeck(int id) throws DAOException {
		Deck deck = em.find(Deck.class, id);
		if(deck==null)
		{
			throw new DAOException("Not existing deck.");
		}
		
		for(Card card: deck.getCards())
		{
			card.getDecks().remove(deck);
			em.merge(card);
		}
		
		deleteCommentsForGameItem(deck.getId());
		
		em.remove(deck);
		
	}

	@Override
	@TransactionAttribute
	public void removeCardfromDeck(int cardID, int deckID) throws DAOException {
		Deck deck = em.find(Deck.class, deckID);
    	if(deck == null)
    	{
    		throw new DAOException("Not exsisting deck.");
    	}
    	
    	Card card = em.find(Card.class, cardID);
    	if(card== null)
    	{
    		throw new DAOException("Not existing card.");
    	}
    	
    	boolean deckContainsCard = false;;
    	for(Card c : deck.getCards())
    	{
    		if(c.getId()==cardID)
    		{
    			deckContainsCard = true;
    		}
    	}
    	if(!deckContainsCard)
    	{
    		throw new DAOException("The deck doesnt contain the card.");
    	}
    	
    	card.getDecks().remove(deck);
    	deck.getCards().remove(card);
    	
    	em.merge(card);
    	em.merge(deck);
		
	}
	
	@Override
	@TransactionAttribute
	public int createUser(String name, String password, Role role) throws DAOException
	{
		List<User> sameNameUser =  em.createQuery("select u from User u where u.name=:name").setParameter("name",name).getResultList(); ;
		if(!sameNameUser.isEmpty())
		{
			throw new DAOException("The name is already used.");
			
		}
		
		User newUser = new User(name, password, role);
		
		em.persist(newUser);
		
		return newUser.getId();
	}
	
	@Override
	@TransactionAttribute
	public void deleteUser(int id) throws DAOException
	{
		User user = em.find(User.class, id);
		if(user==null)
		{
			throw new DAOException("Not existing user.");
		}
		
		
		List<QueryParameter> params = new ArrayList<QueryParameter>();
		
		params.add(new QueryParameter("author",QueryParamOperator.LIKE,user.getName()));
		
		
		List<Deck> decks = getDecks(params);
		List<Card> cards = getCards(params);
		List<Comment> comments = getComments(params);
		
		
		clearSessionforUser(user);
		
		for(Comment comment: comments)
		{
			deleteComment(comment.getId());
		}
		
		
		for(Deck deck: decks)
		{
			deleteDeck(deck.getId());
		}
		
		for(Card card: cards)
		{
			deleteCard(card.getId());
		}
		
		
		
		
		em.remove(user);
	}
	
	@Override
	@TransactionAttribute
	public User getUserData(String name) throws DAOException
	{
		
		List<User> sameNameUser =  em.createQuery("select u from User u where u.name=:name").setParameter("name",name).getResultList(); ;
		if(sameNameUser.isEmpty())
		{
			throw new DAOException("Authentication error.");
			
		}
		if(sameNameUser.size()>1)
		{
			throw new DAOException("Corrupt authentication data.");
		}
		
		User user = sameNameUser.get(0);
		if(user==null)
		{
			throw new DAOException("Not existing user.");
		}
		
		return user;
	}
	
	@Override
	@TransactionAttribute
	public List<Session> getSessionParametersforUser(User user) throws DAOException
	{
		
		return em.createQuery("select s from Session s where s.user=:user").setParameter("user", user).getResultList();
	}
	
	
	
	@Override
	@TransactionAttribute
	public void updateUserSession(User user, String sessionID, Date expDate) throws DAOException
	{
		clearSessionforUser(user);
		
		Session newSession = new Session(user, sessionID, expDate);
		
		em.persist(newSession);
	}
	
	@Override
	@TransactionAttribute
	public void clearSessionforUser(User user)throws DAOException
	{
		
		List<Session> sessions = getSessionParametersforUser(user);
		if(sessions.size()>0)
		{
			for(Session s: sessions)
			{
				em.remove(s);
			}
		}
	}
	
	@Override
	@TransactionAttribute
	public void deleteSessionsExpsBefore(Date date)
	{
		em.createQuery("delete from Session s where s.sessionExp <= :date").setParameter("date", date).executeUpdate();
		
	}
	
	
	@Override
	@TransactionAttribute
    public List<Comment> getComments(List<QueryParameter> params)
    {
    	StringBuilder query = new StringBuilder("select c from Comment c");
    	
    	
    	if(!params.isEmpty())
    	{
    
    		
    		query.append(" where ");
    		
    		int listCounter=1;
	    	for(QueryParameter param : params)
	    	{
	    		
	    		if(param.getParamName().equals("gameItemID"))
	    		{
	    			query.append(" c.gameItem.id ");
	    		}
	    		else if(param.getParamName().equals("author"))
	    		{
	    			query.append(" c.author.name ");
	    		}
	    		else
	    		{
	    			query.append(" c."+param.getParamName()+" ");
	    		}
	    		
	    		
	    		String op = "";
	    		switch (param.getOperator()){
				case LESS:
					op ="<=";
					break;
				case MORE:
					op =">=";
					break;
				case EQUALS:
					op ="=";
					break;
				case LIKE:
					op ="like";
					break;

				default:
					op ="=";
					break;
				}
	    		
	    		query.append(op);
	    		query.append(" :"+param.getParamName()+" ");
	    		
	    		if(listCounter<params.size())
	    		{
	    			query.append(" and ");
	    		}
	    		
	    		listCounter++;
	    		
	    	}
    	}
		Query emQuery = em.createQuery(query.toString());

		for (QueryParameter param : params) {

			if (param.getOperator() == QueryParamOperator.LIKE) {
				String value = (String) param.getValue();
				value = "%" + value + "%";
				emQuery.setParameter(param.getParamName(), value);
			} else {
				emQuery.setParameter(param.getParamName(), param.getValue());
			}

		}

		return emQuery.getResultList();
	}
	
	@Override
	@TransactionAttribute
	public int createComment(String message, Date creationDate, User author, int gameItemID) throws DAOException
	{
		
		GameItem item = em.find(GameItem.class,	 gameItemID);
		if(item==null)
		{
			throw new DAOException("Not existing game item.");
		}
		
		Comment comment = new Comment(message, creationDate, author, item);
		
		em.persist(comment);
		
		return comment.getId();
	}
	
	
	@Override
	@TransactionAttribute
	public void deleteComment(int id) throws DAOException
	{
		Comment comment = em.find(Comment.class, id);
		if(comment == null)
		{
			throw new DAOException("Not existing comment.");
		}
		em.remove(comment);
		
	}
	
	@TransactionAttribute
	private void deleteCommentsForGameItem(int gameItemID) throws DAOException
	{
		List<QueryParameter> commentParamerList = new ArrayList<QueryParameter>();
		commentParamerList.add(new QueryParameter("gameItemID",QueryParamOperator.EQUALS,gameItemID));
		List<Comment> comments = getComments(commentParamerList);
		for(Comment comment : comments)
		{
			deleteComment(comment.getId());
		}
		
	}


	@Override
	public int createAction(String name, String description, String pictureURL
			, User author) throws DAOException {

		Action newAction = new Action(name, description, pictureURL, author);
    	newAction.setCards(new ArrayList<CardAction>());
    	
    	em.persist(newAction);	
    	return newAction.getId();
		
	}


	@Override
	public void updateAction(int id, String name, String description, 
			String pictureURL, String picturePath, int rate)
			throws DAOException {

		Action action = em.find(Action.class,	 id);
		if(action==null)
		{
			throw new DAOException("Not existing action.");
		}
		
		if(name != null)
		{
			action.setName(name);
		}
		
		if(description!=null)
		{
			action.setDescription(description);
		}
		
		if(pictureURL!=null)
		{
			action.setPictureURL(pictureURL);
		}
		
		if(picturePath!=null)
		{
			action.setPicturePath(picturePath);
		}
		
		
		if(rate!=0)
		{
			double currentSum = (action.getRate() * action.getRateCount());
			currentSum+= rate;
			action.setRateCount(action.getRateCount()+1);
			action.setRate(currentSum/action.getRateCount());
		}
		
		em.merge(action);
	}


	@Override
	public void deleteAction(int id) throws DAOException {
		Action action = em.find(Action.class, id);
		if(action==null)
		{
			throw new DAOException("Not existing action.");
		}
		
		for(CardAction cardAction: action.getCards())
		{
			Card card = cardAction.getCard();
			removeActionfromCard(action.getId(), card.getId());
			
			
			em.merge(card);
			em.remove(cardAction);
		}
		
		deleteCommentsForGameItem(action.getId());
		
		em.remove(action);
	}


	@Override
	public void addActiontoCard(int actionID, int cardID, int amount) throws DAOException {
		Action action = em.find(Action.class, actionID);
    	if(action == null)
    	{
    		throw new DAOException("Not exsisting action.");
    	}
    	
    	Card card = em.find(Card.class, cardID);
    	if(card== null)
    	{
    		throw new DAOException("Not existing card.");
    	}
    	/*
    	if(action.getCards()==null)
    	{
    		action.setCards(new ArrayList<Card>());
    	}*/
    	
    	for(CardAction ca : card.getActions())
    	{
    		if(ca.getAction().getId()==actionID)
    		{
    			throw new DAOException("The action is already added to the card.");
    		}
    	}
    	
    	CardAction cardAction = new CardAction(card, action, amount, card.getActions().size()+1);
    	card.getActions().add(cardAction);
    	action.getCards().add(cardAction);
    	
    	em.persist(cardAction);
    	em.merge(card);
    	em.merge(action);
		
	}


	@Override
	public void removeActionfromCard(int actionID, int cardID)
			throws DAOException {
		Action action = em.find(Action.class, actionID);
    	if(action == null)
    	{
    		throw new DAOException("Not exsisting action.");
    	}
    	
    	Card card = em.find(Card.class, cardID);
    	if(card== null)
    	{
    		throw new DAOException("Not existing card.");
    	}
    	
    	CardAction foundCardAction = null;
    	for(CardAction cardAction : card.getActions())
    	{
    		if(cardAction.getAction().getId()==actionID)
    		{
    			foundCardAction = cardAction;
    		}else
    		{
    			if(cardAction.getActionOrder()>foundCardAction.getActionOrder())
    			{
    				cardAction.setActionOrder(cardAction.getActionOrder()-1);
    			}
    		}
    	}
    	if(foundCardAction==null)
    	{
    		throw new DAOException("The card doesnt contain the action.");
    	}
    	
    	card.getActions().remove(foundCardAction);
    	action.getCards().remove(foundCardAction);
    	
    	em.merge(card);
    	em.merge(action);
    	em.remove(foundCardAction);
		
	}
	
	
	@Override
	public void updateActiononCard(int actionID, int cardID, int amount, int order)
			throws DAOException {
		Action action = em.find(Action.class, actionID);
    	if(action == null)
    	{
    		throw new DAOException("Not exsisting action.");
    	}
    	
    	Card card = em.find(Card.class, cardID);
    	if(card== null)
    	{
    		throw new DAOException("Not existing card.");
    	}
    	
    	CardAction foundCardAction = null;
    	for(CardAction cardAction : card.getActions())
    	{
    		if(cardAction.getAction().getId()==actionID)
    		{
    			foundCardAction = cardAction;
    		}
    	}
    	if(foundCardAction==null)
    	{
    		throw new DAOException("The card doesnt contain the action.");
    	}
    	if(order!=0 )
    	{
    		if(foundCardAction.getActionOrder()!= order+1 && foundCardAction.getActionOrder()!= order-1 )
    		{
    			throw new DAOException("Illegal action order change.");
    		}
    		else
    		{
    			for(CardAction ca : card.getActions())
    			{
    				if(ca.getActionOrder()==order)
    				{
    					ca.setActionOrder(ca.getActionOrder()+(foundCardAction.getActionOrder()-order));
    					foundCardAction.setActionOrder(order);
    					break;
    				}
    			}
    		}
    	}
    	
    
    	foundCardAction.setAmount(amount);
    	
    	/*em.merge(foundCardAction);
    	em.merge(card);
    	em.merge(action);*/
    	
		
	}


	@Override
	public List<Action> getActions(List<QueryParameter> params) {
		StringBuilder query = new StringBuilder("select distinct a from Action a left join fetch a.cards ca left join fetch ca.card c ");
    	
		
		
    	if(!params.isEmpty())
    	{
    		
    		query.append(" where ");
    		
    		int listCounter=1;
	    	for(QueryParameter param : params)
	    	{
	    		
	    		if(param.getParamName().equals("cardID"))
	    		{
	    			query.append(" c.id ");
	    		}
	    		else if(param.getParamName().equals("author"))
	    		{
	    			query.append(" a.author.name ");
	    		}
	    		else
	    		{
	    			query.append(" a."+param.getParamName()+" ");
	    		}
	    		
	    		
	    		
	    		query.append(param.getOperator().getOperatorString());
	    		query.append(" :"+param.getParamName()+" ");
	    		
	    		if(listCounter<params.size())
	    		{
	    			query.append(" and ");
	    		}
	    		
	    		listCounter++;
	    		
	    	}
    	}
    	
    	query.append(" order by a.name ");
    	
    	Query emQuery = em.createQuery(query.toString());
    	
    	for(QueryParameter param : params)
    	{
    		if(param.getOperator()== QueryParamOperator.LIKE)
    		{
    			String value = (String) param.getValue();
    			value = "%"+value+"%";
    			emQuery.setParameter(param.getParamName(), value);
    		}
    		else
    		{
    			emQuery.setParameter(param.getParamName(), param.getValue());
    		}
    		
    	}
    	
    	return emQuery.getResultList();
	}


	@Override
	public List<CardAction> getCardActions(List<QueryParameter> params) {
		StringBuilder query = new StringBuilder("select distinct ca from CardAction ca left join fetch ca.action a left join fetch ca.card c ");
    	
		
		
    	if(!params.isEmpty())
    	{
    		
    		query.append(" where ");
    		
    		int listCounter=1;
	    	for(QueryParameter param : params)
	    	{
	    		
	    		if(param.getParamName().equals("cardID"))
	    		{
	    			query.append(" c.id ");
	    		}
	    		else if(param.getParamName().equals("author"))
	    		{
	    			query.append(" a.author.name ");
	    		}
	    		else
	    		{
	    			query.append(" a."+param.getParamName()+" ");
	    		}
	    		
	    		
	    		
	    		query.append(param.getOperator().getOperatorString());
	    		query.append(" :"+param.getParamName()+" ");
	    		
	    		if(listCounter<params.size())
	    		{
	    			query.append(" and ");
	    		}
	    		
	    		listCounter++;
	    		
	    	}
    	}
    	
    	query.append(" order by a.name ");
    	
    	Query emQuery = em.createQuery(query.toString());
    	
    	for(QueryParameter param : params)
    	{
    		if(param.getOperator()== QueryParamOperator.LIKE)
    		{
    			String value = (String) param.getValue();
    			value = "%"+value+"%";
    			emQuery.setParameter(param.getParamName(), value);
    		}
    		else
    		{
    			emQuery.setParameter(param.getParamName(), param.getValue());
    		}
    		
    	}
    	
    	return emQuery.getResultList();
	}


	

	
	
	
	
	
	
	
	
	
   
    
    

}
